#include "ParticleManager.h"
//iostream not needed after test
#include <iostream>
#include <sstream>
#include <string>
#include "../../SGD Wrappers/CSGD_TextureManager.h"



ParticleManager* ParticleManager::GetInstance( void )
{
	static ParticleManager s_Instance;

	return &s_Instance;
}


ParticleManager::ParticleManager(void)
{
	/*Emitter* First = new Emitter();
	First->m_bIsLooping = true;
	First->m_fCurrLife = 42.0f;
	First->m_fElapsedTime = 100.0f;
	First->m_fEndRotation = -1.0f;
	First->m_fEndScale = -1.0f;
	First->m_fEndVelX = -128.0f;
	First->m_fEndVelY = 2.4f;
	First->m_fSpawnRange = 6.9f;
	First->m_fSpawnRate = 2.2f;
	First->m_fStartRotation = 6.7f;
	First->m_fStartScale = 1.4f;
	First->m_fStartVelX = 1.298f;
	First->m_fStartVelY = 5.31f;
	First->m_nEndAlpha = 34;
	First->m_nEndB = 59;
	First->m_nEndG = 74;
	First->m_nEndR = 40;
	First->m_nPartImageID = 809;
	First->m_nPosX = 904;
	First->m_nPosY = 453;
	First->m_nSpawnShape = 617;
	First->m_nStartAlpha = 42;
	First->m_nStartB = 606;
	First->m_nStartG = 687;
	First->m_nStartR = 446;

	AllEmitters.push_back(First);

	Emitter* Second = new Emitter();
	Second->m_bIsLooping = true;
	Second->m_fCurrLife = 46.4f;
	Second->m_fElapsedTime = 46.16f;
	Second->m_fEndRotation = -497.4f;
	Second->m_fEndScale = -4894.45f;
	Second->m_fEndVelX = -7456.16f;
	Second->m_fEndVelY = 794.2f;
	Second->m_fSpawnRange = 496.5f;
	Second->m_fSpawnRate = 4;
	Second->m_fStartRotation = 46.4f;
	Second->m_fStartScale = 45.4f;
	Second->m_fStartVelX = 4.5f;
	Second->m_fStartVelY = 5.31f;
	Second->m_nEndAlpha = 34;
	Second->m_nEndB = 54;
	Second->m_nEndG = 645;
	Second->m_nEndR = 894;
	Second->m_nPartImageID = 489;
	Second->m_nPosX = 6784;
	Second->m_nPosY = 15;
	Second->m_nSpawnShape = 49;
	Second->m_nStartAlpha = 45;
	Second->m_nStartB = 89;
	Second->m_nStartG = 8;
	Second->m_nStartR = 189;

	AllEmitters.push_back(Second);*/
}


ParticleManager::~ParticleManager(void)
{
}

void ParticleManager::Save(const char* SaveParticleFileName)
{

	TiXmlDocument tinyDoc;

	TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "utf-8:", "");

	tinyDoc.LinkEndChild (decl);

	TiXmlElement * Root = new TiXmlElement("Total_Emitters");

	tinyDoc.LinkEndChild(Root);

	for(unsigned int EmIndex = 0; EmIndex < AllEmitters.size(); ++EmIndex)
	{
		TiXmlElement * SaveEmitter = new TiXmlElement("Emitter");

		int IsTrue = 0;
		int TotalPart = AllEmitters[EmIndex]->m_vTotalParticles.size();
		double tempDouble = 0.0f;

		TiXmlElement * TotalParticles = new TiXmlElement("TotalParticles");
		TotalParticles->SetAttribute("Value", TotalPart);
		SaveEmitter->LinkEndChild(TotalParticles);

		TiXmlElement * Loop = new TiXmlElement("IsLooping");
		IsTrue = (int)AllEmitters[EmIndex]->m_bIsLooping;
		Loop->SetAttribute("Value", IsTrue);
		SaveEmitter->LinkEndChild(Loop);

		TiXmlElement * Life = new TiXmlElement("Life");	
		tempDouble = (double)AllEmitters[EmIndex]->m_fCurrLife;
		Life->SetDoubleAttribute( "Value", tempDouble);
		SaveEmitter->LinkEndChild(Life);

		
		TiXmlElement * Range = new TiXmlElement("SpawnRange");	
		tempDouble = (double)AllEmitters[EmIndex]->m_fSpawnRange;
		Range->SetDoubleAttribute( "Value", tempDouble);
		SaveEmitter->LinkEndChild(Range);

		TiXmlElement * Rate = new TiXmlElement("SpawnRate");	
		tempDouble = (double)AllEmitters[EmIndex]->m_fSpawnRate;
		Rate->SetDoubleAttribute( "Value", tempDouble);
		SaveEmitter->LinkEndChild(Rate);

		TiXmlElement * VelocityX = new TiXmlElement("VelocityX");	
		tempDouble = (double)AllEmitters[EmIndex]->m_fStartVelX;
		VelocityX->SetDoubleAttribute( "Start", tempDouble);
		tempDouble = (double)AllEmitters[EmIndex]->m_fEndVelX;
		VelocityX->SetDoubleAttribute( "End", tempDouble);
		SaveEmitter->LinkEndChild(VelocityX);
			
		TiXmlElement * VelocityY = new TiXmlElement("VelocityY");	
		tempDouble = (double)AllEmitters[EmIndex]->m_fStartVelY;
		VelocityY->SetDoubleAttribute( "Start", tempDouble);
		tempDouble = (double)AllEmitters[EmIndex]->m_fEndVelY;
		VelocityY->SetDoubleAttribute( "End", tempDouble);
		SaveEmitter->LinkEndChild(VelocityY);

		TiXmlElement * Rotation = new TiXmlElement("Rotation");	
		tempDouble = (double)AllEmitters[EmIndex]->m_fStartRotation;
		Rotation->SetDoubleAttribute( "Start", tempDouble);
		tempDouble = (double)AllEmitters[EmIndex]->m_fEndRotation;
		Rotation->SetDoubleAttribute( "End", tempDouble);
		SaveEmitter->LinkEndChild(Rotation);
		
		TiXmlElement * Scale = new TiXmlElement("Scale");	
		tempDouble = (double)AllEmitters[EmIndex]->m_fStartScale;
		Scale->SetDoubleAttribute( "Start", tempDouble);
		tempDouble = (double)AllEmitters[EmIndex]->m_fEndScale;
		Scale->SetDoubleAttribute( "End", tempDouble);
		SaveEmitter->LinkEndChild(Scale);
		
		TiXmlElement * Position = new TiXmlElement("Position");	
		tempDouble = (double)AllEmitters[EmIndex]->m_fPosX;
		Position->SetDoubleAttribute( "X", tempDouble);
		tempDouble = (double)AllEmitters[EmIndex]->m_fPosY;
		Position->SetDoubleAttribute( "Y", tempDouble);
		SaveEmitter->LinkEndChild(Position);

		TiXmlElement * ImageID = new TiXmlElement("ImageID");
		TiXmlText * Image = new TiXmlText(AllEmitters[EmIndex]->NameOfImageID);
		ImageID->LinkEndChild(Image);
	
		TiXmlElement * SpawnShape = new TiXmlElement("SpawnShape");	
		SpawnShape->SetDoubleAttribute( "Value", AllEmitters[EmIndex]->m_nSpawnShape);
		SaveEmitter->LinkEndChild(SpawnShape); 

		TiXmlElement * Alpha = new TiXmlElement("Alpha");	
		Alpha->SetDoubleAttribute( "Start", AllEmitters[EmIndex]->m_nStartAlpha);
		Alpha->SetDoubleAttribute( "End", AllEmitters[EmIndex]->m_nEndAlpha);
		SaveEmitter->LinkEndChild(Alpha);

		TiXmlElement * Red = new TiXmlElement("Red");	
		Red->SetDoubleAttribute( "Start", AllEmitters[EmIndex]->m_nStartR);
		Red->SetDoubleAttribute( "End", AllEmitters[EmIndex]->m_nEndR);
		SaveEmitter->LinkEndChild(Red);

		TiXmlElement * Green = new TiXmlElement("Green");	
		Green->SetDoubleAttribute( "Start", AllEmitters[EmIndex]->m_nStartG);
		Green->SetDoubleAttribute( "End", AllEmitters[EmIndex]->m_nEndG);
		SaveEmitter->LinkEndChild(Green);

		TiXmlElement * Blue = new TiXmlElement("Blue");	
		Blue->SetDoubleAttribute( "Start", AllEmitters[EmIndex]->m_nStartB);
		Blue->SetDoubleAttribute( "End", AllEmitters[EmIndex]->m_nEndB);
		SaveEmitter->LinkEndChild(Blue);

		Root->LinkEndChild(SaveEmitter);
		
	}

	tinyDoc.SaveFile(SaveParticleFileName);

}

void ParticleManager::Load(const char* LoadParticleFileName)
{
	TiXmlDocument tinyDoc;

	if(!tinyDoc.LoadFile( LoadParticleFileName))
		return;

	TiXmlElement* Root = tinyDoc.RootElement();

	if( Root == nullptr)
		return;

	AllEmitters.clear();

	TiXmlElement* ReadEmitter = Root->FirstChildElement("Emitter");

	while(ReadEmitter != nullptr)
	{
		int IsTrue = 0;
		int TotalPart = 0;
		double tempDouble = 0.0f;

		Emitter * tempEmitter = new Emitter();

		TiXmlElement * TotalParticles = ReadEmitter->FirstChildElement("TotalParticles");
		TotalParticles->Attribute("Value", &TotalPart);
		tempEmitter->m_nNumOfParticles = TotalPart;

		TiXmlElement * Loop = ReadEmitter->FirstChildElement("IsLooping");
		Loop->Attribute("Value", &IsTrue);
		if(IsTrue == 0)
			tempEmitter->m_bIsLooping = false;
		else
			tempEmitter->m_bIsLooping = true;

		TiXmlElement * Life = ReadEmitter->FirstChildElement("Life");
		Life->Attribute("Value", &tempDouble);
		tempEmitter->m_fCurrLife = (float)tempDouble;


		TiXmlElement * SpawnRange = ReadEmitter->FirstChildElement("SpawnRange");
		SpawnRange->Attribute("Value", &tempDouble);
		tempEmitter->m_fSpawnRange = (float)tempDouble;

		TiXmlElement * SpawnRate = ReadEmitter->FirstChildElement("SpawnRate");
		SpawnRate->Attribute("Value", &tempDouble);
		tempEmitter->m_fSpawnRate = (float)tempDouble;

		TiXmlElement * VelocityX = ReadEmitter->FirstChildElement("VelocityX");
		VelocityX->Attribute("Start", &tempDouble);
		tempEmitter->m_fStartVelX = (float)tempDouble;
		VelocityX->Attribute("End", &tempDouble);
		tempEmitter->m_fEndVelX = (float)tempDouble;

		TiXmlElement * VelocityY = ReadEmitter->FirstChildElement("VelocityY");
		VelocityY->Attribute("Start", &tempDouble);
		tempEmitter->m_fStartVelY = (float)tempDouble;
		VelocityY->Attribute("End", &tempDouble);
		tempEmitter->m_fEndVelY = (float)tempDouble;

		TiXmlElement * Rotation = ReadEmitter->FirstChildElement("Rotation");
		Rotation->Attribute("Start", &tempDouble);
		tempEmitter->m_fStartRotation = (float)tempDouble;
		Rotation->Attribute("End", &tempDouble);
		tempEmitter->m_fEndRotation = (float)tempDouble;

		TiXmlElement * Scale = ReadEmitter->FirstChildElement("Scale");
		Scale->Attribute("Start", &tempDouble);
		tempEmitter->m_fStartScale = (float)tempDouble;
		Scale->Attribute("End", &tempDouble);
		tempEmitter->m_fEndScale = (float)tempDouble;

		TiXmlElement * Position = ReadEmitter->FirstChildElement("Position");
		Position->Attribute("X", &tempDouble);
		tempEmitter->m_fPosX = (float)tempDouble;
		Position->Attribute("Y", &tempDouble);
		tempEmitter->m_fPosY = (float)tempDouble;

		TiXmlElement * ImageID = ReadEmitter->FirstChildElement("ImageID");
		string temp  = "..\\Resource\\Graphics\\";
		temp += ImageID->GetText();
		tempEmitter->NameOfImageID = temp.c_str();
		wostringstream Stuff;
		Stuff << tempEmitter->NameOfImageID;
		tempEmitter->m_nPartImageID = CSGD_TextureManager::GetInstance()->LoadTexture(Stuff.str().c_str());

		TiXmlElement * SpawnShape = ReadEmitter->FirstChildElement("SpawnShape");
		SpawnShape->Attribute("Value", &tempEmitter->m_nSpawnShape);

		TiXmlElement * Alpha = ReadEmitter->FirstChildElement("Alpha");
		Alpha->Attribute("Start", &tempEmitter->m_nStartAlpha);
		Alpha->Attribute("End", &tempEmitter->m_nEndAlpha);

		TiXmlElement * Red = ReadEmitter->FirstChildElement("Red");
		Red->Attribute("Start", &tempEmitter->m_nStartR);
		Red->Attribute("End", &tempEmitter->m_nEndR);

		TiXmlElement * Green = ReadEmitter->FirstChildElement("Green");
		Green->Attribute("Start", &tempEmitter->m_nStartG);
		Green->Attribute("End", &tempEmitter->m_nEndG);

		TiXmlElement * Blue = ReadEmitter->FirstChildElement("Blue");
		Blue->Attribute("Start", &tempEmitter->m_nStartB);
		Blue->Attribute("End", &tempEmitter->m_nEndB);

		//tempEmitter->LoadNewParticles(tempEmitter->m_nNumOfParticles);

		AllEmitters.push_back(tempEmitter);

		ReadEmitter = ReadEmitter->NextSiblingElement("Emitter");
	}

}

void ParticleManager::DestroyEmitters()
{
	for(vector<Emitter*>::iterator Iter = AllEmitters.begin(); Iter != AllEmitters.end(); ++Iter)
	{
		//AllEmitters.erase(Iter);
		delete *Iter;
	}

	AllEmitters.clear();

}

void ParticleManager::Update(float fElapsedTime)
{
	for (unsigned int ParticleIndex = 0; ParticleIndex < AllEmitters.size(); ParticleIndex++)
	{
		AllEmitters[ParticleIndex]->Update(fElapsedTime);
	}
}

void ParticleManager::Render()
{
	for (unsigned int ParticleIndex = 0; ParticleIndex < AllEmitters.size(); ParticleIndex++)
	{
		AllEmitters[ParticleIndex]->Render();
	}
}

//TEST FUNCTION
// Loads an Emitter to the AllEmitters
void ParticleManager::LoadType()
{
	Emitter* First = new Emitter(1000, true, 2.0f, 
		"../Resource/Graphics/PlaceholderImage.png", 
		300.0f, 300.0f, 
		0, 0.01f, 1.0f, 
		255, 255, 255, 0,
		0, 255, 0, 0,
		30.0f, 30.0f, 50.0f, -50.0f, 
		0.0f, 0.0f, 0.5f, 0.5f);		

	AllEmitters.push_back(First);
}
